package com.org.oracle.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.base.Preconditions;
import com.org.oracle.constant.RedisKeyConstants;
import com.org.oracle.enums.ResponseCodeEnum;
import com.org.oracle.exception.CustomException;
import com.org.oracle.mongodb.dto.UserLoginDTO;
import com.org.oracle.mongodb.dto.UserModifyInfoDTO;
import com.org.oracle.mongodb.entity.User;
import com.org.oracle.properties.WeChatProperties;
import com.org.oracle.result.Result;
import com.org.oracle.service.UserService;
import com.org.oracle.thread.UserIdThreadLocal;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author: heiye
 * @date: 2024/10/09 下午9:30
 * @version: v1.0.0
 * @description:
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    // 微信登录接口地址
    private static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";

    @Resource
    private WeChatProperties weChatProperties;

    @Resource
    private MongoTemplate mongoTemplate;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 微信登录
     *
     * @param dto
     * @return
     */
    @Override
    public Result wxLogin(UserLoginDTO dto) {
        try {
            // 校验参数
            Preconditions.checkArgument(Objects.nonNull(dto), ResponseCodeEnum.LOGIN_FAIL);

            log.info("微信用户登录: {}", dto.getCode());

            // 获取openid
//            String openid = getOpenid(dto.getCode());
            String openid = "123456";

            // 校验数据
            Preconditions.checkArgument(StringUtils.isNotBlank(openid), ResponseCodeEnum.LOGIN_FAIL);

            // 查找用户是否注册
            User user = mongoTemplate.findOne(Query.query(Criteria.where("openid").is(openid)), User.class);

            // 用户未注册过自动注册
            if (Objects.isNull(user)) {
                // 获取reid全局唯一uid
                Long uid = (Long) redisTemplate.opsForValue().get(RedisKeyConstants.USER_ID_GENERATOR);

                // 构建用户信息
                user = User.builder()
                        .uid(String.valueOf(uid))
                        .openid(openid)
                        .build();

                // 新增到数据库中
                mongoTemplate.insert(user);
            }

            // 登录用户
            StpUtil.login(user.getUid());

            // 获取token
            String token = StpUtil.getTokenInfo().getTokenValue();

            // 返回数据
            return Result.ok(token);
        } catch (Exception e) {
            // 出错 返回登录失败
            log.error("==================> UserService: 用户微信登录失败");
            return Result.fail(ResponseCodeEnum.LOGIN_FAIL.getErrorMessage());
        }
    }

    /**
     * 修改用户信息
     *
     * @param dto
     * @return
     */
    @Override
    public Result modifyInfo(String uid, UserModifyInfoDTO dto) {
        // 构建查询
        Query query = Query.query(Criteria.where("uid").is(uid));

        // 构建修改
        Update update = new Update();
        update.set("name", dto.getName());
        update.set("avatar", dto.getAvatar());
        update.set("address", dto.getAddress());

        // 修改用户信息
        mongoTemplate.upsert(query, update, User.class);

        return Result.ok();
    }

    /**
     * 基于用户id查找用户信息
     *
     * @return
     */
    @Override
    public Result findUserById(String uid) {
        // 构建查询条件
        Query query = Query.query(Criteria.where("uid").is(uid));

        // 过滤字段
        query.fields().exclude("openid", "uid");

        // 查询
        User user = mongoTemplate.findOne(query, User.class);

        return Result.ok(user);
    }

    /**
     * 调用微信接口服务获取openid
     *
     * @param code
     * @return
     */
    private String getOpenid(String code) {
        //调用微信服务器接口获得openid
        Map<String, Object> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");

        // 发送请求
        String json = HttpUtil.get(WX_LOGIN, map);

        // 解析json
        JSONObject jsonObject = JSON.parseObject(json);

        return jsonObject.getString("openid");
    }
}
